home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / DTP / DTP_TEX / H067.ZIP / JEM2TEX.C < prev    next >
C/C++ Source or Header  |  1991-04-14  |  48KB  |  1,318 lines

  1. /* -mt -f -A -K -G -O -w */
  2. /* Compile with Turbo-C 2.0 */
  3. /*
  4.   This program translates a .JEM file into a .TeX file
  5.  
  6.   Author: Francois Jalbert
  7.               '
  8.   Date: November 1990 
  9.  
  10.   Version: 1.0
  11.  
  12.   Date: January 1991
  13.  
  14.   Version: 1.01
  15.  
  16.   Modifications: - Added \hskip0pt plus0.1em between all Japanese symbols which 
  17.                    improved dramatically line breaks and inter-sentence spacing 
  18.                    since [La]TeX could only add glue between whole Japanese 
  19.                    sentences. 
  20.                  - Extra space after punctuation is now an option since it is 
  21.                    not desirable with MuTeX when the text is to go under the
  22.                    staff. 
  23.                  - Font names now use only small letters to be compatible with 
  24.                    the fontlib program supplied with emTeX. 
  25.                  - Command line parameters now supported.
  26.                  - Run-time parameters now supported.
  27.                  - Updated and improved run-time messages.
  28.  
  29.   Date: April 1991
  30.  
  31.   Version: 2.00
  32.  
  33.   Modifications: - Added four kanjis.
  34.                  - If desired, only standard JIS '83 characters are allowed.
  35.                  - If desired, a % is added at each Japanese end of line.
  36.                  - Three file name extensions .JEM .JPN .JAP now supported.
  37.                  - Default extension is .JEM and the program has been renamed.
  38.                  - Three run-time parameter flags now supported.
  39.                  - Japanese comments not translated anymore for reference.
  40.                  - Hyphenation and glue handled separately for better control.
  41.                  - More clever algorithm for Japanese hyphenation.
  42.                  - Space after some punctuation now obtained with \eeee.
  43.                  - Small space around some punctuation introduced with \eee.
  44.                  - Tiny space between Japanese characters with \ee.
  45.                  - Space between Japanese and Roman with \eeee and \eee.
  46.                  - Symbols separated only by [La]TeX comments are now 
  47.                    recognized as consecutive.
  48.                  - MS-kanji (Shift-JIS) now supported.
  49.  
  50.   Error Levels: 0 - Normal termination.
  51.                 1 - Error.
  52. */
  53.  
  54. #include <stdio.h>
  55. #include <string.h>
  56. #include <ctype.h>
  57. #ifdef __TURBOC__
  58. #include <process.h>
  59. #endif
  60.  
  61. #define True  1
  62. #define False 0
  63. /* Highest Bitmap number in JIS24 */
  64. #define BitmapMax 7806
  65. /* Highest font number */
  66. #define FontMax   60 /* Floor of 7806 Div 128 */
  67. /* Highest size number */
  68. #define SizeMax   7 /* magsteps are 0, 0.5, 1, 2, 3, 4, 5 */
  69. /* DOS file name length */
  70. #define FileNameDOS  250 /* includes path */
  71. #define ExtensionDOS 4   /* includes . */
  72. #define TotalNameDOS 254
  73. /* File name extensions in priority order */
  74. char Extension1[]=".jem";
  75. char Extension2[]=".jpn";
  76. char Extension3[]=".jap";
  77. /* Run-time flag of all the same length */
  78. char RunFlag1[]="JEM2TEX";
  79. char RunFlag2[]="JPN2TEX";
  80. char RunFlag3[]="JAP2TEX";
  81. /* Parameter flag */
  82. #define Flag1 '/' /* DOS style */
  83. #define Flag2 '-' /* UNIX style */
  84. /* Parameter keywords in approximate decreasing length order */
  85. #define ParamMax 12
  86. char Space1[]="EXTRASPACE";
  87. char Space2[]="EXTRA";
  88. char Space3[]="SPACE";
  89. char NoSpace1[]="NOEXTRASPACE";
  90. char NoSpace2[]="NOEXTRA";
  91. char NoSpace3[]="NOSPACE";
  92. char Percent1[]="COMMENT";
  93. char Percent2[]="PERCENT";
  94. char Percent3[]="EOL";
  95. char NoPercent1[]="NOCOMMENT";
  96. char NoPercent2[]="NOPERCENT";
  97. char NoPercent3[]="NOEOL";
  98. char EUC1[]="EUC";
  99. char NoEUC1[]="MSKANJI";
  100. char NoEUC2[]="SHIFTJIS";
  101. char Extended1[]="EXTENDED";
  102. char Standard1[]="STANDARD";
  103. char LaTeX1[]="LATEX";
  104. char TeX1[]="MUTEX";
  105. char TeX2[]="TEX";
  106. char One1[]="1000";
  107. char Two1[]="1095";
  108. char Three1[]="1200";
  109. char Four1[]="1440";
  110. char Five1[]="1728";
  111. char Six1[]="2074";
  112. char Seven1[]="2488";
  113. char One2[]="0.0";
  114. char Two2[]="0.5";
  115. char Three2[]="1.0";
  116. char Four2[]="2.0";
  117. char Five2[]="3.0";
  118. char Six2[]="4.0";
  119. char Seven2[]="5.0";
  120. char One3[]="0";
  121. char Three3[]="1";
  122. char Four3[]="2";
  123. char Five3[]="3";
  124. char Six3[]="4";
  125. char Seven3[]="5";
  126. /* Comment line maximum length */
  127. #define CommentLineMax 254
  128.  
  129. typedef char FileNameType[FileNameDOS+1];
  130. typedef char ExtensionType[ExtensionDOS+1];
  131. typedef char TotalNameType[TotalNameDOS+1];
  132. typedef char ParamType[ParamMax+1];
  133. typedef int FontType[FontMax+1];
  134. typedef FontType FontsType[SizeMax+1];
  135. typedef char CommentLineType[CommentLineMax+2]; /* note the 2 used */
  136. /* Run time parameters */
  137. struct RunTimeType {
  138.   FileNameType FileName;
  139.   ExtensionType Extension;
  140.   int ExtraSpace,Percent,LaTeX,EUC,Extended;
  141.   int Size;
  142. };
  143. /* Japanese punctuation information */
  144. struct PunctuationType {
  145.   /* Indicates .,!? present */
  146.   int OldMajorEOL,NewMajorEOL;
  147.   /* Indicates :; present */
  148.   int OldMinorEOL,NewMinorEOL;
  149.   /* Indicates `"([< and other openings present */
  150.   int OldOpening,NewOpening;
  151.   /* Indicates '")]> and other closings present */
  152.   int OldClosing,NewClosing;
  153.   /* Indicates Japanese center dot present */
  154.   int OldCenterDot,NewCenterDot;
  155.   /* Indicates Hiragana, Katakana, or Kanji present */
  156.   int OldJapanese,NewJapanese;
  157. };
  158. /* Scanning Information */
  159. struct ScanningType {
  160.   /* Current pass terminated */
  161.   int Done;
  162.   /* Indicates the current pass must produce output */
  163.   int Echo;
  164.   /* Indicates the current line is a comment */
  165.   int Comment;
  166.   /* Indicates current Bitmap immediately followed previous one */
  167.   int Immediate;
  168.   /* Indicates the last Roman character was a letter or digit */
  169.   int WasLetter;
  170.   /* Used for glue after a bitmap and before a roman */
  171.   int RomanMajorEOL,RomanMinorEOL,RomanOpening;
  172.   /* Non-comment Bitmap found */
  173.   int Found;
  174.   /* Processing the first character on the line which could be % */
  175.   int First;
  176.   /* Comment line which may contain Bitmaps */
  177.   CommentLineType CommentLine;
  178.   /* Current JIS24 Bitmap number */
  179.   int Bitmap;
  180.   /* Roman or first part of Bitmap read */
  181.   unsigned char Data1;
  182. };
  183.  
  184. void Delete(char *String, int Length)
  185. /* Delete the first Length characters of String */
  186. {
  187.   int Index;
  188.  
  189.   Index=0;
  190.   do String[Index]=String[Index+Length];
  191.   while (String[++Index]!='\0');
  192. }
  193.  
  194. /*----------------------------- EchoParameters ------------------------------*/
  195.  
  196. void EchoParameters(FILE *EchoFile, struct RunTimeType *RunTime)
  197. /* Echoes the current parameters in EchoFile */
  198. {
  199.   fprintf(EchoFile,"File=%s",RunTime->FileName);
  200.   if (RunTime->ExtraSpace) fprintf(EchoFile,"  Space");
  201.   else fprintf(EchoFile,"  No Space");
  202.   if (RunTime->Percent) fprintf(EchoFile,"  Added %%");
  203.   else fprintf(EchoFile,"  No Added %%");
  204.   if (RunTime->LaTeX) fprintf(EchoFile,"  LaTeX");
  205.   else fprintf(EchoFile,"  TeX");
  206.   if (RunTime->EUC) fprintf(EchoFile,"  EUC");
  207.   else fprintf(EchoFile,"  MS-kanji");
  208.   if (RunTime->Extended) fprintf(EchoFile,"  Extended");
  209.   else fprintf(EchoFile,"  Standard");
  210.   fprintf(EchoFile,"  Font Size=");
  211.   switch (RunTime->Size) {
  212.     case 1:fprintf(EchoFile,"1000"); break;
  213.     case 2:fprintf(EchoFile,"1095"); break;
  214.     case 3:fprintf(EchoFile,"1200"); break;
  215.     case 4:fprintf(EchoFile,"1440"); break;
  216.     case 5:fprintf(EchoFile,"1728"); break;
  217.     case 6:fprintf(EchoFile,"2074"); break;
  218.     case 7:fprintf(EchoFile,"2488"); break;
  219.   }
  220.   fprintf(EchoFile,".\n");
  221.   if (ferror(EchoFile)) exit(1);
  222. }
  223.  
  224. /*------------------------------ GetParameters ------------------------------*/
  225.  
  226. void SimpleQuery(char Title[], char ChoiceA[], char ChoiceB[], int *Answer)
  227. {
  228.   char JChar[2];
  229.   int Valid;
  230.  
  231.   do {
  232.     Valid=True;
  233.     printf("%s:\n",Title);
  234.     printf("   a)  %s\n",ChoiceA);
  235.     printf("   b)  %s\n",ChoiceB);
  236.     printf("Your choice? ");
  237.     if (ferror(stdout)) exit(1);
  238.     if (gets(JChar)==NULL) exit(1);
  239.     if (strlen(JChar)>1) exit(1);
  240.     JChar[0]=toupper(JChar[0]);
  241.     if (JChar[0]=='A') *Answer=True;
  242.     else
  243.       if (JChar[0]=='B') *Answer=False;
  244.       else { 
  245.         Valid=False; 
  246.         if (putchar('\7')==EOF) exit(1); 
  247.       }
  248.   } while (!Valid);
  249.   printf("\n");
  250.   if (ferror(stdout)) exit(1);
  251. }
  252.  
  253. void SizeQuery(int *Size)
  254. {
  255.   char JChar[2];
  256.   int Valid;
  257.  
  258.   do {
  259.     Valid=True;
  260.     printf("Japanese Font Size:\n");
  261.     printf("   a)  1000  magstep(0.0)\n");
  262.     printf("   b)  1095  magstep(0.5)\n");
  263.     printf("   c)  1200  magstep(1.0)\n");
  264.     printf("   d)  1440  magstep(2.0)\n");
  265.     printf("   e)  1728  magstep(3.0)\n");
  266.     printf("   f)  2074  magstep(4.5)\n");
  267.     printf("   g)  2488  magstep(5.0)\n");
  268.     printf("Your choice? ");
  269.     if (ferror(stdout)) exit(1);
  270.     if (gets(JChar)==NULL) exit(1);
  271.     if (strlen(JChar)>1) exit(1);
  272.     JChar[0]=toupper(JChar[0]);
  273.     if (('A'<=JChar[0]) && (JChar[0]<='G')) *Size=JChar[0]-'A'+1;
  274.     else { 
  275.       Valid=False; 
  276.       if (putchar('\7')==EOF) exit(1); 
  277.     }
  278.   } while (!Valid);
  279.   printf("\n");
  280.   if (ferror(stdout)) exit(1);
  281. }
  282.  
  283. void Manual(struct RunTimeType *RunTime)
  284. /* Get parameters from user */
  285. {
  286.   printf("Japanese file name? ");
  287.   if (ferror(stdout)) exit(1);
  288.   if (gets(RunTime->FileName)==NULL) exit(1);
  289.   if (strlen(RunTime->FileName)>FileNameDOS) {
  290.     /* File name too long */
  291.     printf("\7File name too long: %s...",RunTime->FileName);
  292.     exit(1);
  293.   }
  294.   printf("\n");
  295.   if (ferror(stdout)) exit(1);
  296.   SimpleQuery("Space around Japanese punctuation","Space","No space",
  297.               &RunTime->ExtraSpace);
  298.   SimpleQuery("Added % at Japanese end of lines","Added %","No added %",
  299.               &RunTime->Percent);
  300.   SimpleQuery("LaTeX or TeX (MuTeX) output","LaTeX","TeX",&RunTime->LaTeX);
  301.   SimpleQuery("EUC or MS-kanji (Shift-JIS) encoding","EUC","MS-kanji",
  302.               &RunTime->EUC);
  303.   SimpleQuery("Extended JIS '83 Bitmaps allowed","Extended","Standard",
  304.               &RunTime->Extended);
  305.   SizeQuery(&RunTime->Size);
  306. }
  307.  
  308. void Automate(struct RunTimeType *RunTime, int argc, char *argv[])
  309. /* Get parameters from command line */
  310. {
  311.   int ParamIndex,ParamLength,Index;
  312.   ParamType Param;
  313.  
  314.   /* Defaults */
  315.   strcpy(RunTime->FileName,"japanese");
  316.   RunTime->ExtraSpace=True;
  317.   RunTime->Percent=True;
  318.   RunTime->LaTeX=True;
  319.   RunTime->EUC=True;
  320.   RunTime->Extended=True;
  321.   RunTime->Size=4;
  322.   /* Scan command line parameters */
  323.   /* 0th is program's name, last is NULL */
  324.   for (ParamIndex=1 ; ParamIndex<argc ; ParamIndex++) {
  325.     ParamLength=strlen(argv[ParamIndex]);
  326.     if (ParamLength>ParamMax) {
  327.       /* Keyword too long */
  328.       printf("\7Invalid command line parameter: %s...",argv[ParamIndex]);
  329.       exit(1);
  330.     }
  331.     strcpy(Param,argv[ParamIndex]);
  332.     if ((Param[0]==Flag1) || (Param[0]==Flag2)) {
  333.       /* Not a filename */
  334.       /* Delete 1 char at the 1st position */
  335.       Delete(Param,1);
  336.       /* Convert to upper case */
  337.       for (Index=0 ; Index<ParamLength ; Index++)
  338.         Param[Index]=toupper(Param[Index]);
  339.       /* Scan known keywords */
  340.       if ( (!strcmp(Param,Space1)) || (!strcmp(Param,Space2)) || 
  341.            (!strcmp(Param,Space3)) ) RunTime->ExtraSpace=True;
  342.       else
  343.       if ( (!strcmp(Param,NoSpace1)) || (!strcmp(Param,NoSpace2)) || 
  344.            (!strcmp(Param,NoSpace3)) ) RunTime->ExtraSpace=False;
  345.       else
  346.       if ( (!strcmp(Param,Percent1)) || (!strcmp(Param,Percent2)) || 
  347.            (!strcmp(Param,Percent3)) ) RunTime->Percent=True;
  348.       else
  349.       if ( (!strcmp(Param,NoPercent1)) || (!strcmp(Param,NoPercent2)) || 
  350.            (!strcmp(Param,NoPercent3)) ) RunTime->Percent=False;
  351.       else
  352.       if (!strcmp(Param,EUC1)) RunTime->EUC=True;
  353.       else
  354.       if ((!strcmp(Param,NoEUC1))||(!strcmp(Param,NoEUC2))) RunTime->EUC=False;
  355.       else
  356.       if (!strcmp(Param,Extended1)) RunTime->Extended=True;
  357.       else
  358.       if (!strcmp(Param,Standard1)) RunTime->Extended=False;
  359.       else
  360.       if (!strcmp(Param,LaTeX1)) RunTime->LaTeX=True;
  361.       else
  362.       if ((!strcmp(Param,TeX1)) || (!strcmp(Param,TeX2))) RunTime->LaTeX=False;
  363.       else
  364.       if ( (!strcmp(Param,One1)) || (!strcmp(Param,One2)) || 
  365.            (!strcmp(Param,One3)) ) RunTime->Size=1;
  366.       else
  367.       if ( (!strcmp(Param,Two1)) || (!strcmp(Param,Two2)) ) RunTime->Size=2;
  368.       else
  369.       if ( (!strcmp(Param,Three1)) || (!strcmp(Param,Three2)) || 
  370.            (!strcmp(Param,Three3)) ) RunTime->Size=3;
  371.       else
  372.       if ( (!strcmp(Param,Four1)) || (!strcmp(Param,Four2)) || 
  373.            (!strcmp(Param,Four3)) ) RunTime->Size=4;
  374.       else
  375.       if ( (!strcmp(Param,Five1)) || (!strcmp(Param,Five2)) || 
  376.            (!strcmp(Param,Five3)) ) RunTime->Size=5;
  377.       else
  378.       if ( (!strcmp(Param,Six1)) || (!strcmp(Param,Six2)) || 
  379.            (!strcmp(Param,Six3)) ) RunTime->Size=6;
  380.       else
  381.       if ( (!strcmp(Param,Seven1)) || (!strcmp(Param,Seven2)) || 
  382.            (!strcmp(Param,Seven3)) ) RunTime->Size=7;
  383.       else {
  384.         /* Unknown keyword */
  385.         printf("\7Invalid command line parameter: %s...\n",Param);
  386.         exit(1);
  387.       }
  388.     }
  389.     else {
  390.       /* Must be a filename, we'll try to open it later */
  391.       if (ParamLength>FileNameDOS) {
  392.         /* File name too long */
  393.         printf("\7File name too long: %s...\n",Param);
  394.         exit(1);
  395.       }
  396.       strcpy(RunTime->FileName,Param);
  397.     }
  398.   }
  399. }
  400.  
  401. void GetParameters(struct RunTimeType *RunTime, int argc, char *argv[])
  402. /* Get parameters from user or command line */
  403. /* Current parameter status is echoed on the console */
  404. {
  405.   /* 0th is program's name, last is NULL */
  406.   if (argc==1) Manual(RunTime);
  407.   else Automate(RunTime,argc,argv);
  408.   EchoParameters(stdout,RunTime);
  409. }
  410.  
  411. /*------------------------------- OpenFile ----------------------------------*/
  412.  
  413. int TryExtension(FILE *(*InFile), struct RunTimeType *RunTime,
  414.                  ExtensionType TriedExtension)
  415. /* Tries to open FileName using TriedExtension */
  416. {
  417.   TotalNameType TotalName;
  418.  
  419.   strcpy(RunTime->Extension,TriedExtension);
  420.   strcpy(TotalName,RunTime->FileName);
  421.   strcat(TotalName,TriedExtension);
  422.   *InFile=fopen(TotalName,"rt");
  423.   return(*InFile!=NULL);
  424. }
  425.  
  426. void OpenFile(FILE *(*InFile), struct RunTimeType *RunTime)
  427. /* Tries to open FileName using all available extensions */
  428. {
  429.   if (TryExtension(InFile,RunTime,Extension1)) printf("%s",Extension1);
  430.   else
  431.     if (TryExtension(InFile,RunTime,Extension2)) printf("%s",Extension2);
  432.     else
  433.       if (TryExtension(InFile,RunTime,Extension3)) printf("%s",Extension3);
  434.       else {
  435.         printf(".\n");
  436.         printf("\7File not found...\n");
  437.         exit(1);
  438.       }
  439. }
  440.  
  441. /*------------------------------- GetBitmap ---------------------------------*/
  442.  
  443. void PerformScan(CommentLineType CommentLine, struct RunTimeType *RunTime,
  444.                  int Echo, FILE *OutFile)
  445. /* Scans the comment line for run-time JEM2TEX parameters */
  446. /* Any Bitmap or unknown parameter stops the scan */
  447. /* Current parameter status is echoed in the .TeX file as a [La]TeX comment */
  448. {
  449.   int Index;
  450.  
  451.   /* Delete 1 char at the 1st position which is % */
  452.   Delete(CommentLine,1);
  453.   /* Convert to upper case */
  454.   for (Index=0 ; Index<strlen(CommentLine) ; Index++)
  455.     CommentLine[Index]=toupper(CommentLine[Index]);
  456.   /* Add space at the line end to characterize premature termination */
  457.   /* Add sentinel at the line end to stop forthcoming loops */
  458.   strcat(CommentLine," %");
  459.   /* Delete leading blanks */
  460.   if (CommentLine[0]==' ')
  461.     do Delete(CommentLine,1);
  462.     while (CommentLine[0]==' '); 
  463.   /* Look for run-time flag at the start of line */
  464.   if ( !strncmp(RunFlag1,CommentLine,strlen(RunFlag1)) ||
  465.        !strncmp(RunFlag2,CommentLine,strlen(RunFlag1)) ||
  466.        !strncmp(RunFlag3,CommentLine,strlen(RunFlag1)) ) {
  467.     /* Remove run-time flag */
  468.     Delete(CommentLine,strlen(RunFlag1));
  469.     /* Scan until sentinel reached */
  470.     do {
  471.       /* Delete leading blanks (inefficient) */
  472.       if (CommentLine[0]==' ')
  473.         do Delete(CommentLine,1);
  474.         while (CommentLine[0]==' '); 
  475.       if ((CommentLine[0]==Flag1) || (CommentLine[0]==Flag2)) {
  476.         /* Valid run-time parameter flag */
  477.         /* Delete 1 char at the 1st position which is flag */
  478.         Delete(CommentLine,1);
  479.         /* Scan in decreasing length order */
  480.         if (!strncmp(Space1,CommentLine,strlen(Space1)))
  481.           { Delete(CommentLine,strlen(Space1)); RunTime->ExtraSpace=True; }
  482.         else
  483.         if (!strncmp(Space2,CommentLine,strlen(Space2)))
  484.           { Delete(CommentLine,strlen(Space2)); RunTime->ExtraSpace=True; }
  485.         else
  486.         if (!strncmp(Space3,CommentLine,strlen(Space3)))
  487.           { Delete(CommentLine,strlen(Space3)); RunTime->ExtraSpace=True; }
  488.         else
  489.         if (!strncmp(NoSpace1,CommentLine,strlen(NoSpace1)))
  490.           { Delete(CommentLine,strlen(NoSpace1)); RunTime->ExtraSpace=False; }
  491.         else
  492.         if (!strncmp(NoSpace2,CommentLine,strlen(NoSpace2)))
  493.           { Delete(CommentLine,strlen(NoSpace2)); RunTime->ExtraSpace=False; }
  494.         else
  495.         if (!strncmp(NoSpace3,CommentLine,strlen(NoSpace3)))
  496.           { Delete(CommentLine,strlen(NoSpace3)); RunTime->ExtraSpace=False; }
  497.         else
  498.         if (!strncmp(Percent1,CommentLine,strlen(Percent1)))
  499.           { Delete(CommentLine,strlen(Percent1)); RunTime->Percent=True; }
  500.         else
  501.         if (!strncmp(Percent2,CommentLine,strlen(Percent2)))
  502.           { Delete(CommentLine,strlen(Percent2)); RunTime->Percent=True; }
  503.         else
  504.         if (!strncmp(Percent3,CommentLine,strlen(Percent3)))
  505.           { Delete(CommentLine,strlen(Percent3)); RunTime->Percent=True; }
  506.         else
  507.         if (!strncmp(NoPercent1,CommentLine,strlen(NoPercent1)))
  508.           { Delete(CommentLine,strlen(NoPercent1)); RunTime->Percent=False; }
  509.         else
  510.         if (!strncmp(NoPercent2,CommentLine,strlen(NoPercent2)))
  511.           { Delete(CommentLine,strlen(NoPercent2)); RunTime->Percent=False; }
  512.         else
  513.         if (!strncmp(NoPercent3,CommentLine,strlen(NoPercent3)))
  514.           { Delete(CommentLine,strlen(NoPercent3)); RunTime->Percent=False; }
  515.         else
  516.         if (!strncmp(EUC1,CommentLine,strlen(EUC1)))
  517.           { Delete(CommentLine,strlen(EUC1)); RunTime->EUC=True; }
  518.         else
  519.         if (!strncmp(NoEUC1,CommentLine,strlen(NoEUC1)))
  520.           { Delete(CommentLine,strlen(NoEUC1)); RunTime->EUC=False; }
  521.         else
  522.         if (!strncmp(NoEUC2,CommentLine,strlen(NoEUC2)))
  523.           { Delete(CommentLine,strlen(NoEUC2)); RunTime->EUC=False; }
  524.         else
  525.         if (!strncmp(Extended1,CommentLine,strlen(Extended1)))
  526.           { Delete(CommentLine,strlen(Extended1)); RunTime->Extended=True; }
  527.         else
  528.         if (!strncmp(Standard1,CommentLine,strlen(Standard1)))
  529.           { Delete(CommentLine,strlen(Standard1)); RunTime->Extended=False; }
  530.         else
  531.         if (!strncmp(LaTeX1,CommentLine,strlen(LaTeX1)))
  532.           { Delete(CommentLine,strlen(LaTeX1)); RunTime->LaTeX=True; }
  533.         else
  534.         if (!strncmp(TeX1,CommentLine,strlen(TeX1)))
  535.           { Delete(CommentLine,strlen(TeX1)); RunTime->LaTeX=False; }
  536.         else
  537.         if (!strncmp(TeX2,CommentLine,strlen(TeX2)))
  538.           { Delete(CommentLine,strlen(TeX2)); RunTime->LaTeX=False; }
  539.         else
  540.         if (!strncmp(One1,CommentLine,strlen(One1)))
  541.           { Delete(CommentLine,strlen(One1)); RunTime->Size=1; }
  542.         else
  543.         if (!strncmp(Two1,CommentLine,strlen(Two1)))
  544.           { Delete(CommentLine,strlen(Two1)); RunTime->Size=2; }
  545.         else
  546.         if (!strncmp(Three1,CommentLine,strlen(Three1)))
  547.           { Delete(CommentLine,strlen(Three1)); RunTime->Size=3; }
  548.         else
  549.         if (!strncmp(Four1,CommentLine,strlen(Four1)))
  550.           { Delete(CommentLine,strlen(Four1)); RunTime->Size=4; }
  551.         else
  552.         if (!strncmp(Five1,CommentLine,strlen(Five1)))
  553.           { Delete(CommentLine,strlen(Five1)); RunTime->Size=5; }
  554.         else
  555.         if (!strncmp(Six1,CommentLine,strlen(Six1)))
  556.           { Delete(CommentLine,strlen(Six1)); RunTime->Size=6; }
  557.         else
  558.         if (!strncmp(Seven1,CommentLine,strlen(Seven1)))
  559.           { Delete(CommentLine,strlen(Seven1)); RunTime->Size=7; }
  560.         else
  561.         if (!strncmp(One2,CommentLine,strlen(One2)))
  562.           { Delete(CommentLine,strlen(One2)); RunTime->Size=1; }
  563.         else
  564.         if (!strncmp(Two2,CommentLine,strlen(Two2)))
  565.           { Delete(CommentLine,strlen(Two2)); RunTime->Size=2; }
  566.         else
  567.         if (!strncmp(Three2,CommentLine,strlen(Three2)))
  568.           { Delete(CommentLine,strlen(Three2)); RunTime->Size=3; }
  569.         else
  570.         if (!strncmp(Four2,CommentLine,strlen(Four2)))
  571.           { Delete(CommentLine,strlen(Four2)); RunTime->Size=4; }
  572.         else
  573.         if (!strncmp(Five2,CommentLine,strlen(Five2)))
  574.           { Delete(CommentLine,strlen(Five2)); RunTime->Size=5; }
  575.         else
  576.         if (!strncmp(Six2,CommentLine,strlen(Six2)))
  577.           { Delete(CommentLine,strlen(Six2)); RunTime->Size=6; }
  578.         else
  579.         if (!strncmp(Seven2,CommentLine,strlen(Seven2)))
  580.           { Delete(CommentLine,strlen(Seven2)); RunTime->Size=7; }
  581.         else
  582.         if (!strncmp(One3,CommentLine,strlen(One3)))
  583.           { Delete(CommentLine,strlen(One3)); RunTime->Size=1; }
  584.         else
  585.         if (!strncmp(Three3,CommentLine,strlen(Three3)))
  586.           { Delete(CommentLine,strlen(Three3)); RunTime->Size=3; }
  587.         else
  588.         if (!strncmp(Four3,CommentLine,strlen(Four3)))
  589.           { Delete(CommentLine,strlen(Four3)); RunTime->Size=4; }
  590.         else
  591.         if (!strncmp(Five3,CommentLine,strlen(Five3)))
  592.           { Delete(CommentLine,strlen(Five3)); RunTime->Size=5; }
  593.         else
  594.         if (!strncmp(Six3,CommentLine,strlen(Six3)))
  595.           { Delete(CommentLine,strlen(Six3)); RunTime->Size=6; }
  596.         else
  597.         if (!strncmp(Seven3,CommentLine,strlen(Seven3)))
  598.           { Delete(CommentLine,strlen(Seven3)); RunTime->Size=7; }
  599.         else
  600.           /* Unknown run-time parameter */
  601.           /* Terminate prematurely current scan */
  602.           strcpy(CommentLine,"%");
  603.         /* Echo status if allowed */
  604.         if ( Echo && strcmp(CommentLine,"%") ) {
  605.           fprintf(OutFile,"%");
  606.           if (ferror(OutFile)) exit(1);
  607.           EchoParameters(OutFile,RunTime);
  608.         }
  609.       }
  610.       else
  611.         /* Unknown run-time parameter flag */
  612.         /* Terminate prematurely current scan */
  613.         strcpy(CommentLine,"%");
  614.     } while (strlen(CommentLine)!=1);
  615.   }
  616. }
  617.  
  618. void LineBreak(FILE *OutFile, int ExtraSpace, struct ScanningType *Scanning)
  619. /* The continuous chain of Bitmaps has just been interrupted by a line break */
  620. /* We know the next Roman character is equivalent to space, i.e. not a letter */
  621. /* A \eeee may be inserted if the previous Bitmap was a .,!? */
  622. /* A \eee may be inserted if the previous Bitmap was a :; center dot )]'" */
  623. /* If glue inserted make sure to leave a totally blank line as present before */
  624. {
  625.   Scanning->Immediate=False;
  626.   if (Scanning->Echo && ExtraSpace)
  627.     if (Scanning->RomanMajorEOL) { 
  628.       fprintf(OutFile,"\\eeee\n");
  629.       if (ferror(OutFile)) exit(1);
  630.     }
  631.     else
  632.       if (Scanning->RomanMinorEOL) {
  633.         fprintf(OutFile,"\\eee\n");
  634.         if (ferror(OutFile)) exit(1);
  635.       }
  636. }
  637.  
  638. void RomanBreak(FILE *OutFile, int ExtraSpace, struct ScanningType *Scanning)
  639. /* The continuous chain of Bitmaps has just been interrupted by a Roman */
  640. /* The next Roman character may be a letter so a \eee is possible */
  641. /* A \eeee may be inserted if the previous Bitmap was a .,!? */
  642. /* A \eee may be inserted if the previous Bitmap was a :; center dot )]'" */
  643. /* Curly brackets are used in \eee and \eeee when the next Roman is a letter */
  644. {
  645.   Scanning->Immediate=False;
  646.   if (Scanning->Echo && ExtraSpace)
  647.     if (Scanning->RomanMajorEOL) {
  648.       if (Scanning->WasLetter) fprintf(OutFile,"\\eeee{}");
  649.       else fprintf(OutFile,"\\eeee");
  650.       if (ferror(OutFile)) exit(1);
  651.     }
  652.     else
  653.       if (Scanning->RomanMinorEOL) {
  654.         if (Scanning->WasLetter) fprintf(OutFile,"\\eee{}");
  655.         else fprintf(OutFile,"\\eee");
  656.         if (ferror(OutFile)) exit(1);
  657.       }
  658.       else
  659.         if (Scanning->WasLetter && !Scanning->RomanOpening) {
  660.           fprintf(OutFile,"\\eee{}");
  661.           if (ferror(OutFile)) exit(1);
  662.         }
  663. }
  664.  
  665. void GotUNIX(FILE *OutFile, struct ScanningType *Scanning,
  666.              struct RunTimeType *RunTime)
  667. /* Handles UNIX EOL */
  668. /* May add glue after the previous Bitmap and before this Roman */
  669. {
  670.   if (Scanning->Immediate)
  671.     if (Scanning->First)
  672.       LineBreak(OutFile,RunTime->ExtraSpace,Scanning);
  673.     else
  674.       if (!Scanning->Comment)
  675.         if (RunTime->Percent)
  676.           if (Scanning->Echo) {
  677.             fprintf(OutFile,"%"); 
  678.             if (ferror(OutFile)) exit(1);
  679.           }
  680.           else ;
  681.         else
  682.           LineBreak(OutFile,RunTime->ExtraSpace,Scanning);
  683.   if (Scanning->Echo) {
  684.     fprintf(OutFile,"\n");
  685.     if (ferror(OutFile)) exit(1);
  686.   }
  687.   if (Scanning->Comment)
  688.     if (!Scanning->First)
  689.       PerformScan(Scanning->CommentLine,RunTime,Scanning->Echo,OutFile);
  690.     else ;
  691.   else
  692.     Scanning->WasLetter=False;
  693.   Scanning->First=True;
  694.   Scanning->Comment=True;
  695.   strcpy(Scanning->CommentLine,"");
  696. }
  697.  
  698. void GotDOS(FILE *OutFile, struct ScanningType *Scanning,
  699.             struct RunTimeType *RunTime, FILE *InFile)
  700. /* Handles DOS EOL */
  701. /* May add glue after the previous Bitmap and before this Roman */
  702. /* An error only stops the current pass to help the user determine its cause */
  703. {
  704.   unsigned char Data2;
  705.  
  706.   GotUNIX(OutFile,Scanning,RunTime);
  707.   /* Line Feed must follow immediately */
  708.   fscanf(InFile,"%c",&Data2);
  709.   if (ferror(InFile)) exit(1);
  710.   if (feof(InFile)) {
  711.     clearerr(InFile);
  712.     Scanning->Done=True;
  713.   }
  714.   else
  715.     if (Data2!=(unsigned char)'\xA') Scanning->Done=True;
  716.   if (Scanning->Done) {
  717.     printf(".\n");
  718.     printf("\7Abnormal DOS end of line..");
  719.     if (ferror(stdout)) exit(1);
  720.   }
  721. }
  722.  
  723. void ValidateBitmap(int Bitmap)
  724. /* Prints a warning when an extended or an empty Bitmap is used */
  725. {
  726.   int Invalid;
  727.  
  728.   Invalid=False;
  729.   if ((109<=Bitmap) && (Bitmap<=119) ) Invalid=True;
  730.   else
  731.   if ((128<=Bitmap) && (Bitmap<=135) ) Invalid=True;
  732.   else
  733.   if ((143<=Bitmap) && (Bitmap<=153) ) Invalid=True;
  734.   else
  735.   if ((169<=Bitmap) && (Bitmap<=175) ) Invalid=True;
  736.   else
  737.   if ((184<=Bitmap) && (Bitmap<=203) ) Invalid=True;
  738.   else
  739.   if ((214<=Bitmap) && (Bitmap<=220) ) Invalid=True;
  740.   else
  741.   if ((247<=Bitmap) && (Bitmap<=252) ) Invalid=True;
  742.   else
  743.   if ((279<=Bitmap) && (Bitmap<=282) ) Invalid=True;
  744.   else
  745.   if (Bitmap==366) Invalid=True;
  746.   else
  747.   if ((463<=Bitmap) && (Bitmap<=470) ) Invalid=True;
  748.   else
  749.   if ((495<=Bitmap) && (Bitmap<=502) ) Invalid=True;
  750.   else
  751.   if ((527<=Bitmap) && (Bitmap<=564) ) Invalid=True;
  752.   else
  753.   if ((598<=Bitmap) && (Bitmap<=612) ) Invalid=True;
  754.   else
  755.   if ((646<=Bitmap) && (Bitmap<=658) ) Invalid=True;
  756.   else
  757.   if ((691<=Bitmap) && (Bitmap<=1410) ) Invalid=True;
  758.   else
  759.   if ((4376<=Bitmap) && (Bitmap<=4418) ) Invalid=True;
  760.   if (Invalid) {
  761.     printf(".\n");
  762.     printf("Warning! The non-standard JIS '83 Bitmap %d encountered",Bitmap);
  763.     if (ferror(stdout)) exit(1);
  764.   }
  765. }
  766.  
  767. void GotBitmap(FILE *OutFile, int EUC, int Extended, FILE *InFile,
  768.                struct ScanningType *Scanning)
  769. /* Handles Bitmap */
  770. /* An error only stops the current pass to help the user determine its cause */
  771. /* If desired, non-standard Bitmaps are pointed out in the first pass */
  772. {
  773.   unsigned char Data2;
  774.   int CommentLength;
  775.  
  776.   if (Scanning->First) {
  777.     /* First character on line */
  778.     Scanning->First=False;
  779.     Scanning->Comment=False;
  780.   }
  781.   fscanf(InFile,"%c",&Data2);
  782.   if (ferror(InFile)) exit(1);
  783.   if (feof(InFile)) {
  784.     clearerr(InFile);
  785.     Scanning->Done=True;
  786.     printf(".\n");
  787.     if (EUC) printf("\7Incomplete EUC character pair..");
  788.     else printf("\7Incomplete MS-kanji character pair..");
  789.     if (ferror(stdout)) exit(1);
  790.   }
  791.   else {
  792.     if (EUC)
  793.       if (((unsigned char)'\xA0'<Data2) && (Data2<(unsigned char)'\xFF'))
  794.         Scanning->Bitmap=94*(int)(Scanning->Data1-(unsigned char)'\xA1')+
  795.                             (int)(Data2-(unsigned char)'\xA1')+1;
  796.       else {
  797.         Scanning->Done=True;
  798.         printf(".\n");
  799.         printf("\7Invalid EUC character pair..");
  800.         if (ferror(stdout)) exit(1);
  801.       }
  802.     else
  803.       if ((((unsigned char)'\x40'<=Data2) && (Data2<=(unsigned char)'\x7E')) ||
  804.           (((unsigned char)'\x80'<=Data2) && (Data2<=(unsigned char)'\xFC'))) {
  805.         if (Scanning->Data1>=(unsigned char)'\xE0') 
  806.           Scanning->Bitmap=1+188*(int)(Scanning->Data1-(unsigned char)'\xC1');
  807.         else
  808.           Scanning->Bitmap=1+188*(int)(Scanning->Data1-(unsigned char)'\x81');
  809.         if (Data2>=(unsigned char)'\x80') 
  810.           Scanning->Bitmap+=(int)(Data2-(unsigned char)'\x41');
  811.         else 
  812.           Scanning->Bitmap+=(int)(Data2-(unsigned char)'\x40');
  813.       }
  814.       else {
  815.         Scanning->Done=True;
  816.         printf(".\n");
  817.         printf("\7Invalid MS-kanji character pair..");
  818.         if (ferror(stdout)) exit(1);
  819.       }
  820.     if (!Scanning->Done)
  821.       /* Bitmaps in comment skipped */
  822.       if (Scanning->Comment) {
  823.         CommentLength=strlen(Scanning->CommentLine);
  824.         if ((CommentLength+1)>=CommentLineMax) {
  825.           /* Comment too long */
  826.           printf(".\n");
  827.           printf("\7Comment too long: %s...\n",Scanning->CommentLine);
  828.           exit(1);
  829.         }
  830.         Scanning->CommentLine[CommentLength]=(char)Scanning->Data1;
  831.         Scanning->CommentLine[CommentLength+1]=(char)Data2;
  832.         Scanning->CommentLine[CommentLength+2]=(char)'\0';
  833.         if (Scanning->Echo) { 
  834.           fprintf(OutFile,"%c%c",Scanning->Data1,Data2);
  835.           if (ferror(OutFile)) exit(1);
  836.         }
  837.       }
  838.       else
  839.         if ( (1<=Scanning->Bitmap) && (Scanning->Bitmap<=BitmapMax) ) {
  840.           Scanning->Found=True;
  841.           /* Point out non-standard Bitmaps in first pass */
  842.           if (!Scanning->Echo && !Extended) ValidateBitmap(Scanning->Bitmap);
  843.         }
  844.         else {
  845.           Scanning->Done=True;
  846.           printf(".\n");
  847.           printf("\7Bitmap %d does not exist..",Scanning->Bitmap);
  848.           if (ferror(stdout)) exit(1);
  849.         }
  850.   }
  851. }
  852.  
  853. void GotRoman(FILE *OutFile, int ExtraSpace,struct ScanningType *Scanning)
  854. /* Handles roman */
  855. /* May add glue after the previous Bitmap and before this Roman */
  856. {
  857.   int CommentLength;
  858.  
  859.   if (Scanning->First) {
  860.     /* First character on line */
  861.     Scanning->First=False;
  862.     if (Scanning->Data1!=(unsigned char)'%') Scanning->Comment=False;
  863.   }
  864.   if (Scanning->Comment) {
  865.     CommentLength=strlen(Scanning->CommentLine);
  866.     if (CommentLength==CommentLineMax) {
  867.       /* Comment too long */
  868.       printf(".\n");
  869.       printf("\7Comment too long: %s...\n",Scanning->CommentLine);
  870.       exit(1);
  871.     }
  872.     Scanning->CommentLine[CommentLength]=(char)Scanning->Data1;
  873.     Scanning->CommentLine[CommentLength+1]=(char)'\0';
  874.   }
  875.   else {
  876.     /* Determine if this roman is a letter or a number */
  877.     Scanning->WasLetter=isalnum(Scanning->Data1);
  878.     if (Scanning->Immediate) RomanBreak(OutFile,ExtraSpace,Scanning);
  879.   }
  880.   if (Scanning->Echo) {
  881.     fprintf(OutFile,"%c",Scanning->Data1);
  882.     if (ferror(OutFile)) exit(1);
  883.   }
  884. }
  885.  
  886. void GetBitmap(FILE *InFile, FILE *OutFile, struct ScanningType *Scanning, 
  887.                struct RunTimeType *RunTime)
  888. /* Scans input file and stops when a Bitmap is met */
  889. /* An error only stops the current pass to help the user determine its cause */
  890. /* Accepts UNIX LF or DOS CR/LF as end of line indicator in input file */
  891. /* Updates JemTeX parameters with run-time parameters */
  892. /* Comment indicates the line is a comment line and does not break continuity */
  893. /* Immediate indicates current Bitmap immediately followed previous Bitmap */
  894. /* If the next character encountered is Roman, glue may be inserted */
  895. /* If desired, will add % at Japanese end of lines to preserve continuity */
  896. {
  897.   /* No Bitmap found initially */
  898.   Scanning->Found=False;
  899.   /* Assume the next character is a Bitmap */
  900.   Scanning->WasLetter=False; 
  901.   Scanning->Immediate=True;
  902.   /* Some non-comment Bitmap was met before or it's the first call to GetBitmap */
  903.   strcpy(Scanning->CommentLine,"");
  904.   /* Comment holds; it's the first call ever to GetBitmap; it's first character */
  905.   /* Comment fails; some non-comment Bitmap was met before; it isnt first char */
  906.   Scanning->First=Scanning->Comment;
  907.   do {
  908.     fscanf(InFile,"%c",&Scanning->Data1);
  909.     if (ferror(InFile)) exit(1);
  910.     if (feof(InFile)) {
  911.       /* File just finished */
  912.       clearerr(InFile);
  913.       Scanning->Done=True;
  914.     }
  915.     else {
  916.       /* More file coming */
  917.       if (Scanning->Data1==(unsigned char)'\xA') 
  918.         GotUNIX(OutFile,Scanning,RunTime);
  919.       else
  920.         if (Scanning->Data1==(unsigned char)'\xC') 
  921.           GotDOS(OutFile,Scanning,RunTime,InFile);
  922.         else
  923.           if (RunTime->EUC)
  924.             if (((unsigned char)'\xA0'<Scanning->Data1) && 
  925.                 (Scanning->Data1<(unsigned char)'\xFF'))
  926.               GotBitmap(OutFile,RunTime->EUC,RunTime->Extended,InFile,Scanning);
  927.             else
  928.               GotRoman(OutFile,RunTime->ExtraSpace,Scanning);
  929.           else
  930.             if ( (((unsigned char)'\x81'<=Scanning->Data1) && 
  931.                   (Scanning->Data1<=(unsigned char)'\x9F')) || 
  932.                  (((unsigned char)'\xE0'<=Scanning->Data1) && 
  933.                   (Scanning->Data1<=(unsigned char)'\xEA')) )
  934.               GotBitmap(OutFile,RunTime->EUC,RunTime->Extended,InFile,Scanning);
  935.             else
  936.               GotRoman(OutFile,RunTime->ExtraSpace,Scanning);
  937.     }
  938.   } while (!Scanning->Done && !Scanning->Found);
  939. }
  940.  
  941. /*--------------------------------- GetFont ---------------------------------*/
  942.  
  943. void GetFont(FILE *InFile, FontsType Fonts, 
  944.              struct RunTimeType *InitialRunTime)
  945. /* Finds the Japanese fonts needed */
  946. /* The last state of LaTeX will prevail for forthcoming header and 2nd pass */
  947. {
  948.   /* Run time parameters */
  949.   struct RunTimeType RunTime;
  950.   /* Current font number */
  951.   int FontPtr;
  952.   int SizePtr;
  953.   /* Scanning information */
  954.   struct ScanningType Scanning;
  955.   /* Dummy since no output in first pass */
  956.   FILE *DummyOutFile=NULL;
  957.  
  958.   strcpy(RunTime.FileName,InitialRunTime->FileName);
  959.   strcpy(RunTime.Extension,InitialRunTime->Extension);
  960.   RunTime.ExtraSpace=InitialRunTime->ExtraSpace;
  961.   RunTime.Percent=InitialRunTime->Percent;
  962.   RunTime.LaTeX=InitialRunTime->LaTeX;
  963.   RunTime.EUC=InitialRunTime->EUC;
  964.   RunTime.Extended=InitialRunTime->Extended;
  965.   RunTime.Size=InitialRunTime->Size;
  966.   /* No Japanese font needed so far */
  967.   for (SizePtr=1 ; SizePtr<=SizeMax ; SizePtr++)
  968.     for (FontPtr=0 ; FontPtr<=FontMax ; FontPtr++)
  969.       Fonts[SizePtr][FontPtr]=False;
  970.   /* Not reached EOF yet */
  971.   Scanning.Done=False;
  972.   /* No echo in first pass */
  973.   Scanning.Echo=False;
  974.   /* Dummy since no output in first pass */
  975.   Scanning.Immediate=False;
  976.   Scanning.WasLetter=False;
  977.   Scanning.RomanMajorEOL=False;
  978.   Scanning.RomanMinorEOL=False;
  979.   Scanning.RomanOpening=False;
  980.   /* Tell indirectly to GetBitmap that this is the first time it is called */
  981.   Scanning.Comment=True;
  982.   do {
  983.     /* Get the next Bitmap skipping over [La]TeX comments */
  984.     GetBitmap(InFile,DummyOutFile,&Scanning,&RunTime);
  985.     if (!Scanning.Done) Fonts[RunTime.Size][Scanning.Bitmap/128]=True;
  986.   } while (!Scanning.Done);
  987.   /* Last state of LaTeX prevails for the second pass */
  988.   InitialRunTime->LaTeX=RunTime.LaTeX;
  989. }
  990.  
  991. /*---------------------------------- Header ---------------------------------*/
  992.  
  993. void Header(FILE *OutFile, FontsType Fonts, int LaTeX)
  994. /* Writes [La]TeX header */
  995. {
  996.   int FontPtr;
  997.   int SizePtr;
  998.   char C0,C1,C2;
  999.   int Scale;
  1000.  
  1001.   fprintf(OutFile,"\\tracingstats=1\n");
  1002.   if (ferror(OutFile)) exit(1);
  1003.   for (SizePtr=1 ; SizePtr<=SizeMax ; SizePtr++) {
  1004.     C0='a'+(char)(SizePtr-1);
  1005.     switch (SizePtr)
  1006.       {
  1007.       case 1:Scale=1000; break;
  1008.       case 2:Scale=1095; break;
  1009.       case 3:Scale=1200; break;
  1010.       case 4:Scale=1440; break;
  1011.       case 5:Scale=1728; break;
  1012.       case 6:Scale=2074; break;
  1013.       case 7:Scale=2488; break;
  1014.       }
  1015.     for (FontPtr=0 ; FontPtr<=FontMax ; FontPtr++)
  1016.       if (Fonts[SizePtr][FontPtr]) {
  1017.         C1='a'+(char)(FontPtr / 8);
  1018.         C2='a'+(char)(FontPtr % 8);
  1019.         if (LaTeX)
  1020.           fprintf(OutFile,"\\newfont{\\k%c%c%c}{kanji%c%c scaled %d}\n",
  1021.                   C0,C1,C2,C1,C2,Scale);
  1022.         else
  1023.           fprintf(OutFile,"\\font\\k%c%c%c=kanji%c%c scaled %d\n",
  1024.                   C0,C1,C2,C1,C2,Scale);
  1025.         if (ferror(OutFile)) exit(1);
  1026.       }
  1027.   }
  1028.   if (LaTeX) {
  1029.     fprintf(OutFile,"\\newcommand{\\kk}[2]{{#1\\symbol{#2}}}\n");
  1030.     fprintf(OutFile,"\\newcommand{\\hh}{\\discretionary{}{}{}}\n");
  1031.     fprintf(OutFile,"\\newcommand{\\ee}{\\nobreak\\hskip0pt plus.1em\\relax}\n");
  1032.     fprintf(OutFile,"\\newcommand{\\eee}{\\nobreak\\hskip.3em plus.1em\\relax}\n");
  1033.     fprintf(OutFile,"\\newcommand{\\eeee}{\\nobreak\\hskip.9em plus.1em minus.1em}\n");
  1034.   }
  1035.   else {
  1036.     fprintf(OutFile,"\\def\\kk#1#2{{#1\\char#2}}\n");
  1037.     fprintf(OutFile,"\\def\\hh{\\discretionary{}{}{}}\n");
  1038.     fprintf(OutFile,"\\def\\ee{\\nobreak\\hskip0pt plus.1em\\relax}\n");
  1039.     fprintf(OutFile,"\\def\\eee{\\nobreak\\hskip.3em plus.1em\\relax}\n");
  1040.     fprintf(OutFile,"\\def\\eeee{\\nobreak\\hskip.9em plus.1em minus.1em}\n");
  1041.   }
  1042.   fprintf(OutFile,"\n");
  1043.   if (ferror(OutFile)) exit(1);
  1044. }
  1045.  
  1046. /*--------------------------------- Convert ---------------------------------*/
  1047.  
  1048. void BitmapType(int Bitmap, struct PunctuationType *Punctuation)
  1049. /* Finds characteristics of current Bitmap */
  1050. {
  1051.   Punctuation->OldMajorEOL=Punctuation->NewMajorEOL;
  1052.   Punctuation->OldMinorEOL=Punctuation->NewMinorEOL;
  1053.   Punctuation->OldOpening=Punctuation->NewOpening;
  1054.   Punctuation->OldClosing=Punctuation->NewClosing;
  1055.   Punctuation->OldCenterDot=Punctuation->NewCenterDot;
  1056.   Punctuation->OldJapanese=Punctuation->NewJapanese;
  1057.   Punctuation->NewMajorEOL=False;
  1058.   Punctuation->NewMinorEOL=False;
  1059.   Punctuation->NewOpening=False;
  1060.   Punctuation->NewClosing=False;
  1061.   Punctuation->NewCenterDot=False;
  1062.   Punctuation->NewJapanese=False;
  1063.   /* Full width .,!? */
  1064.   if ((2<=Bitmap) && (Bitmap<=5)) Punctuation->NewMajorEOL=True;
  1065.   else
  1066.   if ((Bitmap==9) || (Bitmap==10)) Punctuation->NewMajorEOL=True;
  1067.   else
  1068.   /* Half width .,!? */
  1069.   if ((Bitmap==691) || (Bitmap==720)) Punctuation->NewMajorEOL=True;
  1070.   else
  1071.   /* Full width :; */
  1072.   if ((Bitmap==7) || (Bitmap==8)) Punctuation->NewMinorEOL=True;
  1073.   else
  1074.   /* Half width :; */
  1075.   if ((Bitmap==692) || (Bitmap==693)) Punctuation->NewMinorEOL=True;
  1076.   else
  1077.   /* Full width `"([< and other openings */
  1078.   if ((38<=Bitmap) && (Bitmap<=58) && !(Bitmap%2)) Punctuation->NewOpening=True;
  1079.   else
  1080.   /* Half width `"([< and other openings */
  1081.   if ((696<=Bitmap)&& (Bitmap<=716)&& !(Bitmap%2)) Punctuation->NewOpening=True;
  1082.   else
  1083.   /* Full width '")]> and other closings */
  1084.   if ((39<=Bitmap) && (Bitmap<=59) && (Bitmap%2)) Punctuation->NewClosing=True;
  1085.   else
  1086.   /* Half width '")]> and other closings */
  1087.   if ((697<=Bitmap) && (Bitmap<=717)&& (Bitmap%2)) Punctuation->NewClosing=True;
  1088.   else
  1089.   /* Full width Japanese center dot */
  1090.   if (Bitmap==6) Punctuation->NewCenterDot=True;
  1091.   else
  1092.   /* Half width Japanese center dot */
  1093.   if (Bitmap==469) Punctuation->NewCenterDot=True;
  1094.   else
  1095.   /* Full width Hiragana */
  1096.   if ((283<=Bitmap) && (Bitmap<=365)) Punctuation->NewJapanese=True;
  1097.   else
  1098.   /* Full width Katakana */
  1099.   if ((377<=Bitmap) && (Bitmap<=462)) Punctuation->NewJapanese=True;
  1100.   else
  1101.   /* Full width Kanji level 1 */
  1102.   if ((1411<=Bitmap) && (Bitmap<=4375)) Punctuation->NewJapanese=True;
  1103.   else
  1104.   /* Full width Kanji level 2 */
  1105.   if ((4419<=Bitmap) && (Bitmap<=7806)) Punctuation->NewJapanese=True;
  1106.   else
  1107.   /* Script Hiragana */
  1108.   if ((753<=Bitmap) && (Bitmap<=835)) Punctuation->NewJapanese=True;
  1109.   else
  1110.   /* Script Katakana */
  1111.   if ((847<=Bitmap) && (Bitmap<=932)) Punctuation->NewJapanese=True;
  1112. }
  1113.  
  1114. void Hyphenate(FILE *OutFile, struct PunctuationType *Punctuation)
  1115. /* Adds hyphenation between consecutive Bitmaps */
  1116. {
  1117.   /* No hyphenation between two odd symbols */
  1118.   if (Punctuation->OldJapanese || Punctuation->NewJapanese)
  1119.     /* No hyphenation before some symbols */
  1120.     if (!Punctuation->NewMajorEOL && !Punctuation->NewMinorEOL && 
  1121.         !Punctuation->NewCenterDot && !Punctuation->NewClosing)
  1122.       /* No hyphenation after some symbols */
  1123.       if (!Punctuation->OldOpening) {
  1124.         fprintf(OutFile,"\\hh");
  1125.         if (ferror(OutFile)) exit(1);
  1126.       }
  1127. }
  1128.  
  1129. void Glue(FILE *OutFile, struct PunctuationType *Punctuation, int ExtraSpace)
  1130. /* Adds glue between consecutive Bitmaps */
  1131. {
  1132.   int GlueAdded;
  1133.  
  1134.   GlueAdded=False;
  1135.   if (ExtraSpace) {
  1136.     /* Trying to add big glue */
  1137.     if (Punctuation->OldMajorEOL)
  1138.       /* No big glue between identical symbols */
  1139.       if (!Punctuation->NewMajorEOL)
  1140.         /* No big glue before some symbols */
  1141.         if (!Punctuation->NewClosing) {
  1142.           GlueAdded=True;
  1143.           fprintf(OutFile,"\\eeee");
  1144.           if (ferror(OutFile)) exit(1);
  1145.         }
  1146.     if (!GlueAdded)
  1147.       /* Trying to add medium glue based on old symbol */
  1148.       if (Punctuation->OldMinorEOL || Punctuation->OldCenterDot || 
  1149.           Punctuation->OldClosing)
  1150.         /* No medium glue before some symbols */
  1151.         if (!Punctuation->NewMajorEOL && !Punctuation->NewMinorEOL && 
  1152.             !Punctuation->NewClosing) {
  1153.           GlueAdded=True;
  1154.           fprintf(OutFile,"\\eee");
  1155.           if (ferror(OutFile)) exit(1);
  1156.         }
  1157.     if (!GlueAdded)
  1158.       /* Trying to add medium glue based on new symbol */
  1159.       if (Punctuation->NewCenterDot || Punctuation->NewOpening)
  1160.         /* No medium glue after some symbols */
  1161.         if (!Punctuation->OldOpening) {
  1162.           GlueAdded=True;
  1163.           fprintf(OutFile,"\\eee");
  1164.           if (ferror(OutFile)) exit(1);
  1165.         }
  1166.   }
  1167.   /* Always make sure to add some glue */
  1168.   if (!GlueAdded) {
  1169.     /* Adding small glue */
  1170.     fprintf(OutFile,"\\ee");
  1171.     if (ferror(OutFile)) exit(1);
  1172.   }
  1173. }
  1174.  
  1175. void Convert(FILE *InFile, FILE *OutFile, struct RunTimeType *RunTime)
  1176. /* Convert .JEM into .TeX by translating Bitmaps & adding hyphenation & glue */
  1177.   /* Japanese punctuation information */
  1178.   struct PunctuationType Punctuation;
  1179.   /* Scanning information */
  1180.   struct ScanningType Scanning;
  1181.   /* Current font number */
  1182.   int FontPtr;
  1183.   char C0,C1,C2;
  1184.  
  1185.   /* Not reached EOF yet */
  1186.   Scanning.Done=False;
  1187.   /* Echo in second pass */
  1188.   Scanning.Echo=True;
  1189.   /* Nothing done yet */
  1190.   Scanning.Immediate=False;
  1191.   Scanning.WasLetter=False;
  1192.   /* Tell indirectly to GetBitmap that this is the first time it is called */
  1193.   Scanning.Comment=True;
  1194.   /* Initial japanese punctuation information */
  1195.   Punctuation.NewMajorEOL=False; Punctuation.NewMinorEOL=False;
  1196.   Punctuation.NewOpening=False; Punctuation.NewClosing=False;
  1197.   Punctuation.NewCenterDot=False; Punctuation.NewJapanese=False;
  1198.   do {
  1199.     /* Set up scanning information in case a roman letter follows immediately */
  1200.     Scanning.RomanMajorEOL=Punctuation.NewMajorEOL;
  1201.     Scanning.RomanMinorEOL=(Punctuation.NewMinorEOL || 
  1202.                             Punctuation.NewCenterDot || 
  1203.                             Punctuation.NewClosing);
  1204.     Scanning.RomanOpening=Punctuation.NewOpening;
  1205.     /* Get the next Bitmap skipping over [La]TeX comments */
  1206.     /* May add glue between the old Bitmap and an hypothetical Roman */
  1207.     GetBitmap(InFile,OutFile,&Scanning,RunTime);
  1208.     if (!Scanning.Done) {
  1209.       /* Find what kind of Bitmap it is */
  1210.       BitmapType(Scanning.Bitmap,&Punctuation);
  1211.       if (Scanning.Immediate) {
  1212.         /* Add hyphenation and glue between consecutive Bitmaps */
  1213.         Hyphenate(OutFile,&Punctuation);
  1214.         Glue(OutFile,&Punctuation,RunTime->ExtraSpace);
  1215.       }
  1216.       else
  1217.         /* Add glue after the old Roman and before this new Bitmap */
  1218.         if (RunTime->ExtraSpace)
  1219.           if (Punctuation.NewCenterDot || Punctuation.NewOpening) {
  1220.             fprintf(OutFile,"\\eee");
  1221.             if (ferror(OutFile)) exit(1);
  1222.           }
  1223.           else 
  1224.             if (Scanning.WasLetter)
  1225.               /* No medium glue before some symbols */
  1226.               if (!Punctuation.NewMajorEOL && !Punctuation.NewMinorEOL && 
  1227.                   !Punctuation.NewClosing) {
  1228.                 fprintf(OutFile,"\\eee");
  1229.                 if (ferror(OutFile)) exit(1);
  1230.               }
  1231.       /* Write the Bitmap */
  1232.       C0='a'+(char)(RunTime->Size-1);
  1233.       FontPtr=Scanning.Bitmap / 128;
  1234.       C1='a'+(char)(FontPtr / 8);
  1235.       C2='a'+(char)(FontPtr % 8);
  1236.       fprintf(OutFile,"\\kk{\\k%c%c%c}{%d}",C0,C1,C2,(Scanning.Bitmap % 128));
  1237.       if (ferror(OutFile)) exit(1);
  1238.       /* The next character may be Roman, GetBitmap will handle the glue then */
  1239.     }
  1240.   } while (!Scanning.Done);
  1241. }
  1242.  
  1243. /*----------------------------------- Main ----------------------------------*/
  1244.  
  1245. main(int argc, char *argv[])
  1246. {
  1247.   /* Input and Output file names */
  1248.   TotalNameType TotalName;
  1249.   FILE *InFile;
  1250.   FILE *OutFile;
  1251.   /* Run time parameters */
  1252.   struct RunTimeType RunTime;
  1253.   /* JemTeX fonts used */
  1254.   FontsType Fonts;
  1255.  
  1256.   printf("\n");
  1257.   printf("Japanese to [La]TeX Conversion Program.\n"); /*To make Borland happy*/
  1258.   printf("Version 2.00 Copyright F. Jalbert 1991.\n");
  1259.   printf("\n");
  1260.   if (ferror(stdout)) exit(1);
  1261.  
  1262.   GetParameters(&RunTime,argc,argv);
  1263.   printf("\n");
  1264.   printf("Opening Japanese file %s",RunTime.FileName);
  1265.   OpenFile(&InFile,&RunTime);
  1266.   printf(".\n");
  1267.   if (RunTime.LaTeX) printf("Creating LaTeX file %s.tex",RunTime.FileName);
  1268.   else printf("Creating TeX file %s.tex",RunTime.FileName);
  1269.   strcpy(TotalName,RunTime.FileName);
  1270.   strcat(TotalName,".tex");
  1271.   OutFile=fopen(TotalName,"wt");
  1272.   if (OutFile==NULL) exit(1);
  1273.   printf(".\n");
  1274.   printf("\n");
  1275.   if (ferror(stdout)) exit(1);
  1276.  
  1277.   printf("Scanning Japanese file for fonts");
  1278.   #ifndef __TURBOC__
  1279.   printf("\n");
  1280.   #endif
  1281.   GetFont(InFile,Fonts,&RunTime);
  1282.   rewind(InFile);
  1283.   /* ferror now cleared */
  1284.   printf(".\n");
  1285.   if (RunTime.LaTeX) printf("Writing LaTeX header");
  1286.   else printf("Writing TeX header");
  1287.   #ifndef __TURBOC__
  1288.   printf("\n");
  1289.   #endif
  1290.   Header(OutFile,Fonts,RunTime.LaTeX);
  1291.   printf(".\n");
  1292.   printf("Converting Japanese file");
  1293.   #ifndef __TURBOC__
  1294.   printf("\n");
  1295.   #endif
  1296.   Convert(InFile,OutFile,&RunTime);
  1297.   printf(".\n");
  1298.   printf("\n");
  1299.   if (ferror(stdout)) exit(1);
  1300.  
  1301.   printf("Closing Japanese file %s%s",RunTime.FileName,RunTime.Extension);
  1302.   if (fclose(InFile)==EOF) exit(1);
  1303.   printf(".\n");
  1304.   if (RunTime.LaTeX) printf("Closing LaTeX file %s.tex",RunTime.FileName);
  1305.   else printf("Closing TeX file %s.tex",RunTime.FileName);
  1306.   if (fclose(OutFile)==EOF) exit(1);
  1307.   printf(".\n");
  1308.   printf("\n");
  1309.   if (ferror(stdout)) exit(1);
  1310.  
  1311.   printf("Japanese to [La]TeX conversion completed.\n");
  1312.   printf("\n");
  1313.   if (ferror(stdout)) exit(1);
  1314.  
  1315.   return(0);
  1316. }
  1317.